package com.xrit.security;

import com.xrit.pojo.UserInfo;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import java.util.ArrayList;
import java.util.List;

/**
 * 进阶3：需要实现UserDetailsService返回给SpringSecurity，才会帮我们做真实用户数据的认证和登录
 */
public class UserService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //1.从数据库查询到的
        UserInfo user = findByUsername(username);
        /**
         * 2.security需要的登陆用户信息:
         * 用户名(String username)、密码(String password,密码是铭文必须{noop}声明)、权限集合(authorities)
         */
        //2.1.初始角色和权限的集合(GrantedAuthority：角色和权限共用接口),并添加角色和权限
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        //添加1个角色(角色必须带"ROLE_")
        GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_ADMIN");
        authorities.add(authority);
        //添加1个权限(不带“ROLE_”的就是权限)
        authority = new SimpleGrantedAuthority("add");
        authorities.add(authority);

        //2.2.将security需要登陆用户信息添加进org.springframework.security.core.userdetails.User，并返回
       User securityUser = new User(username,user.getPassword(),authorities);
        return securityUser;
    }

    /**
     * 假设从数据库查询
     */
    private UserInfo findByUsername (String username){
        if("peng".equals(username)) {
            UserInfo user = new UserInfo();
            user.setUserName("peng");
            user.setPassword("$2a$10$u/BcsUUqZNWUxdmDhbnoeeobJy6IBsL1Gn/S0dMxI2RbSgnMKJ.4a");
            return user;
        }
        return null;
    }

    /**
     * 测试BCryptPasswordEncoder加密
     */
    public static void main(String[] args) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        // encode加密
        System.out.println(encoder.encode("1234"));

        // 密码匹配:明文,密文
        System.out.println(encoder.matches("1234", "$2a$10$XOripk.Z/c2X5.AJdWxrEOSX9vNc9A8jmrDyCcdXcLZS7BGuATq0G"));
        System.out.println(encoder.matches("1234", "$2a$10$7y4NCbRaAMvdr0RYgs8f5eyiwy28vvOO0.Hcy2neUDt5UpWfpSgTm"));
        System.out.println(encoder.matches("1234", "$2a$10$qzHiyQc.Xn78nkurepFJAeED2A3BIFgnQh/RP89ZeTZMIueb2i4jK"));
        System.out.println(encoder.matches("1234", "$2a$10$XOripk.Z/c2X5.AJdWxrEOSX9vNc9A8jmrDyCcdXcLZS7BGuATq0G"));
    }
}
